package com.ldzl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ldzl.dto.ItemDetailDTO;
import com.ldzl.dto.ItemReceiptDTO;
import com.ldzl.pojo.*;
import com.ldzl.service.*;
import com.ldzl.mapper.CkItemRecptMapper;
import org.aspectj.lang.annotation.AfterThrowing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author 风止
* @description 针对表【ck_item_recpt(物料入库单表)】的数据库操作Service实现
* @createDate 2025-07-18 16:44:31
*/
@Service
@Transactional
public class CkItemRecptServiceImpl extends ServiceImpl<CkItemRecptMapper, CkItemRecpt>
    implements CkItemRecptService{
    @Autowired
    private CkPurchaseOrderLineService pols; // 采购订单行服务
    @Autowired
    private CkItemRecptLineService rls; // 入库单行服务
    @Autowired
    private CkStockDetailService sds; // 库存详情服务
    @Autowired
    private CkBatchService cbs; // 批次服务

    @Lazy
    @Autowired
    private CkWarehouseService ws; // 仓库服务
    @Autowired
    private CkStorageLocationService sls; // 库区服务
    @Autowired
    private CkStorageAreaService sas; // 库位服务
    @Autowired
    private CkWarningService cws; // 预警服务

    /**
     * 查询入库单
     * @param itemRecpt
     * @return
     */
    @Override
    public List<CkItemRecpt> selectRecpt(CkItemRecpt itemRecpt) {
        return super.baseMapper.selectRecpt(itemRecpt);
    }

    /**
     * 新增入库单
     * @param itemReceiptDTO
     * @return
     */
    @Override
    public boolean addRecpt(ItemReceiptDTO itemReceiptDTO) {
        //获取采购订单信息
        CkItemRecpt itemRecpt = itemReceiptDTO.getItemRecpt();
        //获取采购订单行信息
        List<ItemDetailDTO> listItemDetail = itemReceiptDTO.getListItemDetail();

        //判断是否为修改
        boolean isUpdate = itemRecpt.getRecpt_id() != null;

        Date date = new Date(); //当前日期
        //1.添加采购订单信息
        itemRecpt.setCreate_time(date);//创建日期
        itemRecpt.setUpdate_time(date);//修改日期
        if(super.saveOrUpdate(itemRecpt)){
            //2.添加采购订单行信息
            List<CkItemRecptLine> listRecptLine = new ArrayList<>();
            listItemDetail.forEach(item -> {
                CkItemRecptLine line = new CkItemRecptLine();
                line.setLine_id(item.getLine_id());
                line.setRecpt_id(itemRecpt.getRecpt_id());
                line.setOrder_line_id(item.getOrder_line_id());
                line.setGoods_code(item.getGoods_code());
                line.setGoods_name(item.getGoods_name());
                line.setStock_sfn(item.getStock_sfn());
                line.setUnit_name(item.getUnit_name());
                //判断 修改后的本次入库数量是否 大于采购订单行待入库数量
                if(isUpdate){
                    if(item.getReceipt_num().compareTo(item.getTreat_list_num()) > 0){
                        line.setRecived_num(item.getReceipt_num());
                        System.out.println("测试入库的入库商品数量****："+line.getRecived_num());
                        //修改采购订单详情 待入库数量
                        pols.updateArrived_num(item.getOrder_line_id(),
                                item.getReceipt_num().subtract(item.getTreat_list_num()));
                    }else if(item.getReceipt_num().compareTo(item.getTreat_list_num()) < 0){
                        line.setRecived_num(item.getReceipt_num());

                        System.out.println("测试回退的入库商品："+item.getGoods_name());
                        System.out.println("测试回退的入库商品数量：" +
                                item.getTreat_list_num().subtract(item.getReceipt_num()));
                        //回退 修改采购订单详情 待入库数量
                        pols.updateArrived_num_back(item.getOrder_line_id(),
                                item.getTreat_list_num().subtract(item.getReceipt_num()));
                    }else{
                        line.setRecived_num(item.getReceipt_num());
                    }

                }else{
                    line.setRecived_num(item.getReceipt_num());
                    System.out.println("修改采购订单详情 待入库数量："+item.getReceipt_num());
                    //修改采购订单详情 待入库数量
                    pols.updateArrived_num(item.getOrder_line_id(), item.getReceipt_num());
                }
                line.setBatch_code(itemRecpt.getBatch_code());
                line.setMaterial_classification_id(item.getMaterial_classification_id());
                line.setMaterial_subcategory_id(item.getMaterial_subcategory_id());
                line.setLocation_id(item.getLocation_id());
                line.setLocation_name(item.getLocation_name());
                line.setArea_id(item.getArea_id());
                line.setArea_name(item.getArea_name());
                line.setProduce_date(item.getProduction_date());
                line.setExpire_date(item.getExpiry_date());
                line.setRemark(item.getRemark());
                if(!isUpdate){
                    line.setCreate_by(itemRecpt.getCreate_by());
                    line.setCreate_time(date);
                }
                line.setUpdate_by(itemRecpt.getUpdate_by());
                line.setUpdate_time(date);

                listRecptLine.add(line); //添加采购订单行
            });

            //修改采购订单时查找 被移除的采购商品
            if(isUpdate){
                List<CkItemRecptLine> listLine = rls.selectRecptLine_feedback(itemRecpt.getRecpt_id());
                listRecptLine.forEach(line -> {
                    listLine.removeIf(line2 -> line.getLine_id().equals(line2.getLine_id()));
                });
                //移除采购订单行
                listLine.forEach( line -> {
                    System.out.println("移除采购订单行：" + line.getRecived_num());
                    pols.updateArrived_num_back(line.getOrder_line_id(),
                            line.getRecived_num());
                    rls.updateIs_delete(line.getLine_id());
                });
            }

            listRecptLine.forEach(line -> {
                System.out.println("测试获取的商品："+line.getRecived_num());
            });
            return rls.saveOrUpdateBatch(listRecptLine);
        }
        return false;
    }

    /**
     * 提交入库单
     * @param recpt_id
     * @return
     */
    @Override
    public boolean submitReceipt(Long recpt_id) {
        CkItemRecpt itemRecpt = new CkItemRecpt();
        itemRecpt.setRecpt_id(recpt_id);
        itemRecpt.setStatus("2");
        return super.saveOrUpdate(itemRecpt);
    }

    /**
     * 入库
     * @param itemRecpt
     * @return
     */
    @Override
    public boolean goodsWarehousing(CkItemRecpt itemRecpt) {
        //1.查询入库单下的商品详情
        List<CkItemRecptLine> listLine = rls.list(new QueryWrapper<CkItemRecptLine>()
                .eq("recpt_id",itemRecpt.getRecpt_id())
                .eq("is_delete",0)
        );
        //查询仓库信息
        CkWarehouse warehouse = ws.getOne(new QueryWrapper<CkWarehouse>()
                .eq("warehouse_name",itemRecpt.getWarehouse_name())
                .eq("is_delete",0)
        );

        //2.给对应的商品增加库存
        listLine.forEach(line -> {
            if(line.getStatus().equals("2")){
                //查询出库位信息
                CkStorageArea area2 = sas.getOne(new QueryWrapper<CkStorageArea>()
                        .eq("area_id",line.getArea_id())
                        .eq("is_delete",0)
                );

                //增加库位的 已用容量
                CkStorageArea area3 = new CkStorageArea();
                area3.setArea_id(line.getArea_id());
                //单位转换 暂不处理
                area3.setCurrent_weight(area2.getCurrent_weight().add(line.getRecived_num()));
                area3.setUpdate_by(itemRecpt.getUpdate_by());
                area3.setUpdate_time(new Date());
                if(!sas.saveOrUpdate(area3))
                    System.out.println("修改库位已用容量失败,库位id："+line.getArea_id());

                CkStockDetail stockDetail = sds.getOne(new QueryWrapper<CkStockDetail>()
                        .eq("item_code",line.getGoods_code())
                        .eq("unit_name",line.getUnit_name())
                        .eq("batch_code",line.getBatch_code())
                        .eq("warehouse_name",itemRecpt.getWarehouse_name())
                        .eq("location_name",line.getLocation_name())
                        .eq("area_name",line.getArea_name())
                        .eq("is_delete",0)
                );
                //判断此商品是否有库存
                if(stockDetail != null){
                    //有库存 增加库存数量
                    CkStockDetail updateStock = new CkStockDetail(); //需要修改的数据
                    updateStock.setItem_id(stockDetail.getItem_id());
                    updateStock.setQuantity_num(line.getRecived_num().add(stockDetail.getQuantity_num()));
                    updateStock.setUpdate_time(new Date());
                    updateStock.setUpdate_by(itemRecpt.getUpdate_by());
                    if(sds.saveOrUpdate(updateStock))
                        System.out.println("修改库存数量："+line.getRecived_num());
                    else
                        System.out.println("修改库存数量失败："+line.getRecived_num());
                }else{
                    //没有库存 新增库存记录
                    CkStockDetail insertStock = new CkStockDetail(); //新增的数据
                    insertStock.setItem_code(line.getGoods_code());
                    insertStock.setItem_name(line.getGoods_name());
                    insertStock.setUnit_name(line.getUnit_name());
                    //查询批次id
                    CkBatch batch = cbs.getOne(new QueryWrapper<CkBatch>()
                            .eq("batch_code",line.getBatch_code())
                            .eq("is_delete",0)
                    );
                    System.out.println("获取的批次id："+line);
                    System.out.println("批次id："+batch);

                    insertStock.setBatch_id(batch.getBatch_id());
                    insertStock.setBatch_code(line.getBatch_code());
                    insertStock.setProduce_time(line.getProduce_date());
                    //仓库三件套
                    insertStock.setWarehouse_id(itemRecpt.getWarehouse_id());
                    insertStock.setWarehouse_code(warehouse.getWarehouse_code());
                    insertStock.setWarehouse_name(itemRecpt.getWarehouse_name());
                    //查询库区
                    CkStorageLocation location = sls.getOne(new QueryWrapper<CkStorageLocation>()
                            .eq("location_name",line.getLocation_name())
                            .eq("is_delete",0)
                    );
                    insertStock.setLocation_id(line.getLocation_id());
                    insertStock.setLocation_code(location.getLocation_code());
                    insertStock.setLocation_name(line.getLocation_name());
                    // 查询库区
                    CkStorageArea area = sas.getOne(new QueryWrapper<CkStorageArea>()
                            .eq("area_name",line.getArea_name())
                            .eq("is_delete",0)
                    );

                    insertStock.setArea_id(line.getArea_id());
                    insertStock.setArea_code(area.getArea_code());
                    insertStock.setArea_name(line.getArea_name());
                    insertStock.setQuantity_num(line.getRecived_num());
                    insertStock.setReserved_num(new BigDecimal(0));
                    insertStock.setMaterial_classification_id(line.getMaterial_classification_id());
                    insertStock.setMaterial_subcategory_id(line.getMaterial_subcategory_id());
                    insertStock.setStock_sfn(line.getStock_sfn());
                    insertStock.setCreate_by(itemRecpt.getUpdate_by());
                    insertStock.setCreate_time(new Date());
                    insertStock.setUpdate_by(itemRecpt.getUpdate_by());
                    insertStock.setUpdate_time(new Date());

                    //查询是否有 库存上下限
                    CkWarning warning = cws.getOne(new QueryWrapper<CkWarning>()
                            .eq("warehouse_id", itemRecpt.getWarehouse_id())
                            .eq("product_code", line.getGoods_code())
                            .eq("is_delete", 0)
                    );
                    if(warning == null){
                        warning = new CkWarning();
                        warning.setWarehouse_id(itemRecpt.getWarehouse_id());
                        warning.setProduct_code(line.getGoods_code());
                        warning.setProduct_name(line.getGoods_name());
                        warning.setUnit_name(line.getUnit_name());
                        warning.setMax_stock(new BigDecimal(5000));
                        warning.setMin_stock(new BigDecimal(100));
                        warning.setCreate_by(itemRecpt.getUpdate_by());
                        warning.setCreate_time(new Date());
                        warning.setUpdate_by(itemRecpt.getUpdate_by());
                        warning.setUpdate_time(new Date());
                        warning.setIs_delete("0");
                        if (cws.save( warning))
                            System.out.println("保存库存预警成功");
                        else
                            System.out.println("保存库存预警失败");
                    }

                    if(sds.saveOrUpdate(insertStock))
                        System.out.println(line.getGoods_name()+",增加库存："+line.getRecived_num());
                    else
                        System.out.println("增加库存失败："+line.getRecived_num());
                }
            }

            //3.增加对应商品的上架数量  只有采购入库才增加
            if(itemRecpt.getStorage_type().equals("1") && line.getOrder_line_id() != null){
                pols.updateList_num(line.getOrder_line_id(),line.getRecived_num());
            }
        });
        //4.修改订单状态
        Date date = new Date();
        CkItemRecpt updateStatus = new CkItemRecpt(); //修改状态 为已入库
        updateStatus.setRecpt_date( date);
        updateStatus.setRecpt_id(itemRecpt.getRecpt_id());
        updateStatus.setStatus("6");
        updateStatus.setUpdate_time( date);
        updateStatus.setUpdate_by(itemRecpt.getUpdate_by());
        return super.saveOrUpdate(updateStatus);
    }

    /**
     * 查询待质检的入库单
     * @param recpt_code
     * @param recpt_name
     * @return
     */
    @Override
    public List<CkItemRecpt> selectCkProductRecptDetectSingle(String recpt_code, String recpt_name,String  status) {
        return super.baseMapper.selectCkProductRecptDetectSingle(recpt_code,recpt_name, status);
    }

    /**
     * 修改入库单状态 合格或不合格
     * @param recpt_id
     * @param status
     * @return
     */
    @Override
    public boolean updateCkProductRecptStatusStatus(Long recpt_id, Long status) {
        return super.baseMapper.updateCkProductRecptStatusStatus(recpt_id,status) > 0;
    }

    /**
     * 根据仓库删除入库单
     * @param warehouse_id
     * @return
     */
    @Override
    public boolean delete_warehouse_id(Long warehouse_id) {
        return super.baseMapper.delete_warehouse_id(warehouse_id) > 0;
    }

    /**
     * 删除入库单
     * @param itemRecpt
     * @return
     */
    @Override
    public boolean deleteRecpt(CkItemRecpt itemRecpt) {
        //获取入库单下的入库商品详情
        /*List<CkItemRecptLine> itemRecptLineList = rls

        //判断删除的入库单是否时 已入库的
        if(itemRecpt.getStatus().equals("6")){
            //删除状态为已入库的  入库单
        }else{
            line.setRecived_num(item.getReceipt_num());

            System.out.println("测试回退的入库商品："+item.getGoods_name());
            System.out.println("测试回退的入库商品数量：" +
                    item.getTreat_list_num().subtract(item.getReceipt_num()));
            //回退 修改采购订单详情 待入库数量
            pols.updateArrived_num_back(item.getOrder_line_id(),
                    item.getTreat_list_num().subtract(item.getReceipt_num()));
        }*/

        return false;
    }

    /**
     * 批量删除入库单
     * @param list_recpt_id
     * @return
     */
    @Override
    public boolean deleteRecpt_batch(List<Long> list_recpt_id) {
        List<CkItemRecpt> listRecpt = new ArrayList<>(); //批量删除入库单

        //遍历入库单id 查询出所有订单信息
        for (Long recpt_id : list_recpt_id) {
            CkItemRecpt itemRecpt = super.getOne(new QueryWrapper<CkItemRecpt>()
                    .eq("recpt_id", recpt_id)
                    .eq("is_delete", 0)
            );
            if(itemRecpt.getStatus().equals("1")){
                List<CkItemRecptLine> lineList = rls.list(new QueryWrapper<CkItemRecptLine>()
                        .eq("recpt_id", recpt_id)
                        .eq("is_delete", 0)
                );
                for (CkItemRecptLine line : lineList) {
                    //查询采购详情信息
                    CkPurchaseOrderLine item = pols.getOne(new QueryWrapper<CkPurchaseOrderLine>()
                            .eq("line_id", line.getOrder_line_id())
                            .eq("is_delete", 0)
                    );
                    //回退 修改采购订单详情 待入库数量
                    pols.updateArrived_num_back(line.getOrder_line_id(),
                            line.getRecived_num());

                }

            }
            //移除入库单商品信息
            if(!rls.delete_recpt_id(recpt_id))
                System.out.println("删除入库单商品失败，入库单id为："+recpt_id);
            CkItemRecpt delete = new CkItemRecpt();
            delete.setRecpt_id(recpt_id);
            delete.setIs_delete("1");
            listRecpt.add(delete);
        }
        return super.saveOrUpdateBatch(listRecpt);
    }


}




